'\" te
.\" Copyright (c) 2006, Sun Microsystems, Inc., All Rights Reserved
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
.TH USB_PIPE_INTR_XFER 9F "Sep 16, 2016"
.SH NAME
usb_pipe_intr_xfer, usb_pipe_stop_intr_polling \- USB interrupt transfer and
polling functions
.SH SYNOPSIS
.nf
#include <sys/usb/usba.h>



\fBint\fR \fBusb_pipe_intr_xfer\fR(\fBusb_pipe_handle_t\fR \fIpipe_handle\fR, \fBusb_intr_req_t *\fR\fIrequest\fR,
     \fBusb_flags_t\fR \fIflags\fR);
.fi

.LP
.nf
\fBvoid\fR \fBusb_pipe_stop_intr_polling\fR(\fBusb_pipe_handle_t\fR \fIpipe_handle\fR, \fBusb__flags_t\fR \fIflags\fR);
.fi

.SH INTERFACE LEVEL
illumos DDI specific (illumos DDI)
.SH PARAMETERS
For \fBusb_pipe_intr_xfer()\fR:
.sp
.ne 2
.na
\fB\fIpipe_handle\fR\fR
.ad
.RS 15n
Interrupt pipe handle on which request is made.
.RE

.sp
.ne 2
.na
\fB\fIrequest\fR\fR
.ad
.RS 15n
Pointer to interrupt transfer request.
.RE

.sp
.ne 2
.na
\fB\fIflags\fR\fR
.ad
.RS 15n
USB_FLAGS_SLEEP is the only flag recognized. Wait for needed resources if
unavailable. For requests specifying the USB_ATTRS_ONE_XFER attribute, wait for
the request to complete.
.RE

.sp
.LP
For \fBusb_pipe_stop_intr_polling()\fR:
.sp
.ne 2
.na
\fB\fIpipe_handle\fR\fR
.ad
.RS 15n
Interrupt pipe handle on which to stop polling for data.
.RE

.sp
.ne 2
.na
\fB\fIflags\fR\fR
.ad
.RS 15n
USB_FLAGS_SLEEP is the only flag recognized. Wait for polling to stop.
.RE

.SH DESCRIPTION
The \fBusb_pipe_intr_xfer()\fR function requests the USBA framework to perform
a transfer through a USB interrupt pipe. The request is passed to the host
controller driver (HCD), which performs the necessary transactions to complete
the request.
.sp
.LP
There are three categories of interrupt transfers: periodic or polled
interrupt-IN, single-transfer interrupt-IN, and (single-transfer)
interrupt-OUT.
.SS "Periodic Interrupt-IN Transfers"
Periodic or polled interrupt-IN transfers execute on input requests which do
not have the USB_ATTRS_ONE_XFER attribute set. One request enables repetitive
transfers at a periodic rate set by the endpoint's bInterval. There can be only
one interrupt-IN request submitted at a time.
.sp
.LP
Periodic interrupt-IN transfers are always asynchronous. Client driver
notification of new data is always via a callback. The USB_FLAGS_SLEEP flag is
only to wait for resources to become available. Callbacks must always be in
place to receive transfer completion notification. Please see
\fBusb_callback_flags\fR(9S) for details on USB callbacks.
.sp
.LP
Calls made to \fBusb_pipe_intr_xfer()\fR for starting input polling need
allocate only one request. The USBA framework allocates a new request each time
polling has new data to return.  (Note that each request returned must be freed
via \fBusb_free_intr_req\fR(9F). Specify a zero length when calling
\fBusb_alloc_intr_req()\fR to allocate the original request, since it will not
be used to return data.  Set the intr_len in the request to specify how much
data can be returned per polling interval.
.sp
.LP
The original request passed to \fBusb_pipe_intr_xfer()\fR is used to return
status when polling is terminated, or on an error condition when the
USB_ATTRS_AUTOCLEARING attribute is set for the request. If autoclearing is not
set, the current (non-original) request is returned on error. Call
\fBusb_pipe_reset\fR(9F) to reset the pipe and get back the original request in
this case. The USB_CR_STOPPED_POLLING flag is always set for callbacks where
the original request is returned.
.SS "Single-transfer Interrupt-IN Transfers"
Interrupt-IN requests which have the USB_ATTRS_ONE_XFER attribute perform a
single transfer. Such requests are synchronous when the USB_FLAGS_SLEEP flag is
specified. Calls for synchronous requests do not return until their transaction
is complete, and their callbacks are optional. The request is returned to the
client through the normal or the exception completion callback to signal either
normal completion or an error condition.
.SS "Interrupt-OUT Transfers"
Interrupt-OUT requests always set up for a single transfer. However, multiple
requests can be queued and execute in periodic fashion until depleted.
.sp
.LP
Interrupt-OUT transfers are synchronous when the USB_FLAGS_SLEEP flag is set in
the request's flags. Calls for synchronous transfers will not return until
their transaction has completed. Calls for asynchronous transfers notify the
client driver of transaction completion via a normal callback, or error
completion via an exception callback.
.sp
.LP
The \fBusb_pipe_stop_intr_polling()\fR function terminates polling on
interrupt-IN pipes and does the following:
.br
.in +2
1. Cease polling.
.in -2
.br
.in +2
2. Allow any requests-in-progress to complete and be returned to the client
driver through the normal callback mechanism.
.in -2
.br
.in +2
3. Idle the pipe.
.in -2
.br
.in +2
4. Return the original polling request to the client driver through an
exception callback with a completion reason of USB_CR_STOPPED_POLLING.
.in -2
.sp
.LP
The client driver may restart polling from an exception callback only if the
callback corresponds to an original request. The callback handler checks for
the following completion reasons to ensure that a callback corresponds to an
original request:
.sp
.in +2
.nf
        USB_CR_STOPPED_POLLING,
        USB_CR_PIPE_RESET,
        USB_CR_PIPE_CLOSING,
        USB_CR_NOT_SUPPORTED
.fi
.in -2

.sp
.LP
The callback handler also checks the request's intr_data field to mark original
polling requests, when the requests are created with a zero \fIlen\fR argument.
In this case, a NULL intr_data field distinguishes a returned original request
from a request allocated by the framework during polling.
.sp
.LP
Mblks for data for interrupt-OUT requests are allocated when a request is
allocated via \fBusb_alloc_intr_req\fR(9F) by passing a non-negative value for
the \fIlen\fR argument.
.SH RETURN VALUES
For \fBusb_pipe_intr_xfer()\fR
.sp
.ne 2
.na
\fBUSB_SUCCESS\fR
.ad
.RS 25n
Transfer was successful.
.RE

.sp
.ne 2
.na
\fBUSB_INVALID_ARGS\fR
.ad
.RS 25n
Request is \fBNULL\fR.
.RE

.sp
.ne 2
.na
\fBUSB_INVALID_CONTEXT\fR
.ad
.RS 25n
Called from interrupt context with the USB_FLAGS_SLEEP flag set.
.RE

.sp
.ne 2
.na
\fBUSB_INVALID_REQUEST\fR
.ad
.RS 25n
The request has been freed or otherwise invalidated.
.sp
A set of conflicting attributes was specified. See \fBusb_intr_request\fR(9S).
.sp
The normal and/or  exception callback was NULL, USB_FLAGS_SLEEP was not set and
USB_ATTRS_ONE_XFER was not set.
.sp
An interrupt request was  specified with a NULL data and a non-zero intr_len
value.
.sp
An IN interrupt request was specified with both polling (USB_ATTRS_ONE_XFER
clear in attributes) and non-zero timeout specified.
.sp
An IN interrupt request was specified with a  non-NULL data argument.
.sp
An OUT interrupt request was specified with a NULL data argument.
.RE

.sp
.ne 2
.na
\fBUSB_INVALID_PIPE\fR
.ad
.RS 25n
Pipe handle is NULL or invalid.
.sp
Pipe is closing or closed.
.RE

.sp
.ne 2
.na
\fBUSB_PIPE_ERROR\fR
.ad
.RS 25n
Pipe handle refers to a pipe which is in the USB_PIPE_STATE_ERROR state.
.RE

.sp
.ne 2
.na
\fBUSB_NO_RESOURCES\fR
.ad
.RS 25n
Memory, descriptors or other resources unavailable.
.RE

.sp
.ne 2
.na
\fBUSB_HC_HARDWARE_ERROR\fR
.ad
.RS 25n
Host controller is in error state.
.RE

.sp
.ne 2
.na
\fBUSB_FAILURE\fR
.ad
.RS 25n
An asynchronous transfer failed or an internal error occurred.
.sp
An intr polling request is made while polling is already in progress.
.sp
The pipe is in an unsuitable state (error, busy, not ready).
.sp
Additional status information may be available in the intr_completion_reason
and intr_cb_flags fields of the request. Please see
\fBusb_completion_reason\fR(9S) and \fBusb_callback_flags\fR(9S) for more
information.
.RE

.sp
.LP
For \fBusb_pipe_stop_intr_polling()\fR
.sp
.LP
None, but fails if called with USB_FLAGS_SLEEP specified from interrupt
context, pipe handle is invalid, NULL or pertains to a closing or closed pipe,
or the pipe is in an error state. Error messages are logged to the console
logfile.
.sp
.LP
Exception handlers' queued requests which are flushed by these commands before
execution are returned with completion reason of USB_CR_FLUSHED.
.SH CONTEXT
Both of these functions can be called from kernel or user context without
regard to arguments, and may be called from interrupt context only when the
USB_FLAGS_SLEEP flag is clear.
.SH EXAMPLES
.in +2
.nf
 /* Start polling on interrupt-IN pipe. */

 usb_intr_req_t intr_req;
 void intr_pipe_callback(usb_pipe_handle_t, usb_intr_req_t*);
 void intr_pipe_exception_callback(
     usb_pipe_handle_t, usb_intr_req_t*);
 usb_ep_descr_t *ep_descr;

 ep_descr = ...;
 intr_req = usb_alloc_intr_req(dip, 0, USB_FLAGS_SLEEP);
 ...
 ...
 intr_req->intr_attributes   = USB_ATTRS_SHORT_XFER_OK;
 intr_req->intr_len          = ep_descr->wMaxPacketSize;
 ...
 ...
 intr_req->intr_cb           = intr_pipe_callback;
 intr_req->intr_exc_cb       = intr_pipe_exception_callback;

 if ((rval = usb_pipe_intr_xfer(pipe, intr_req, USB_FLAGS_NOSLEEP))
     != USB_SUCCESS) {
       cmn_err (CE_WARN, "%s%d: Error starting interrupt pipe polling.",
           ddi_driver_name(dip), ddi_get_instance(dip));
 }

 -------

 /* Stop polling before setting device idle.  Wait for polling to stop. */

 usb_pipe_stop_intr_polling(pipe, USB_FLAGS_SLEEP);
 (void) pm_idle_component(dip, 0);

 -------

 /* Allocate, initialize and issue a synchronous intr-OUT request. */

 usb_intr_req_t intr_req;
 mblk_t *mblk;
 usb_ep_descr_t *ep_descr;

 ep_descr = ...;

 intr_req =
   usb_alloc_intr_req(dip, ep_descr->wMaxPacketSize, USB_FLAGS_SLEEP);

 intr_req->intr_attributes   = USB_ATTRS_AUTOCLEARING;
 mblk = intr_req->intr_data;
 bcopy(buffer, mblk->b_wptr, ep_descr->wMaxPacketSize);
 mblk->b_wptr += ep_descr->wMaxPacketSize;

 if ((rval = usb_pipe_intr_xfer(pipe, intr_req, USB_FLAGS_SLEEP))
     != USB_SUCCESS) {
         cmn_err (CE_WARN, "%s%d: Error writing intr data.",
             ddi_driver_name(dip), ddi_get_instance(dip));
 }

.fi
.in -2

.SH ATTRIBUTES
See \fBattributes\fR(7) for descriptions of the following attributes:
.sp

.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE	ATTRIBUTE VALUE
_
Architecture	PCI-based systems
_
Interface stability	Evolving
.TE

.SH SEE ALSO
.BR attributes (7),
.BR usb_alloc_request (9F),
.BR usb_get_cfg (9F),
.BR usb_get_status (9F),
.BR usb_pipe_bulk_xfer (9F),
.BR usb_pipe_ctrl_xfer (9F),
.BR usb_pipe_get_state (9F),
.BR usb_pipe_isoc_xfer (9F),
.BR usb_pipe_reset (9F),
.BR usb_pipe_xopen (9F),
.BR usb_bulk_request (9S),
.BR usb_callback_flags (9S),
.BR usb_completion_reason (9S),
.BR usb_ctrl_request (9S),
.BR usb_ep_descr (9S),
.BR usb_intr_request (9S),
.BR usb_isoc_request (9S)
